package main

import (
	"btcionshow/ch01-test01/utils"
	"bytes"
	"fmt"
	"math/big"
	"strconv"
)

/**
 * @author: SuZhiXiaoWei
 * @DateTime: 2022/2/28 9:39
 **/
const BITS = 2

type ProofOfWork struct {
	Block  *Block
	Target *big.Int
}

/**
实列化一个pow结构体并且返回
*/
func NewPow(block *Block) *ProofOfWork {
	target := big.NewInt(1) //声明一个大整数类型的1
	//hash值256位 向左移BITS位
	target = target.Lsh(target, 255-BITS)
	pow := ProofOfWork{
		Block:  block,
		Target: target,
	}
	return &pow
}

//用来寻找随机数
func (pow *ProofOfWork) Run() ([]byte, int64) {
	var nonce int64 //随机数
	nonce = 0
	block := pow.Block
	//将int类型转为string类型
	time := []byte( strconv.FormatInt(block.TimeStamp, 10))
	num := big.NewInt(0)
	//循环移动位数，直到满足退出条件
	for {
		//拼接字符串 第一个参数要拼接的内容，第二个是以什么形式拼接
		random := []byte( strconv.FormatInt(nonce, 10))
		//把[]byte转成大整数类型
		hashbytes := bytes.Join([][]byte{block.PrevHash, block.Data, time, random}, []byte{})
		hash := utils.GetHash(hashbytes)
		fmt.Println("正在寻找随机数，当前随机数位：", nonce)
		num = num.SetBytes(hash)
		if num.Cmp(pow.Target) == -1 {
			return hash, nonce
		}
		nonce++
	}
	return nil, 0
}
